﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace KDG.FoldersSize
{
    public partial class DriveScan : Component
    {
        private string folder;
        private DirInfo driveInfo = null;
        private bool scaning;

        public DriveScan()
        {
            InitializeComponent();

        }

        public void Scan()
        {
            DirectoryInfo di = new DirectoryInfo(folder);
            
            if(di.Exists)
                backgroundWorker1.RunWorkerAsync();
            else
                throw new Exception("Folder is not exist.");
        }

        private DirInfo ScanFolder(DirInfo dirInfo, DoWorkEventArgs e)
        {
            DirectoryInfo di = new DirectoryInfo(dirInfo.FullPath);
            if (backgroundWorker1.CancellationPending)
            {
                e.Cancel = true;
                return dirInfo;
            }

            backgroundWorker1.ReportProgress(0, dirInfo.FullPath);
            try
            {
                FileInfo[] fis=di.GetFiles();
                foreach (FileInfo file in fis)
                {
                    dirInfo.Files.Add(file);
                    dirInfo.TotalLenght += file.Length;
                    dirInfo.FilesLenght += file.Length;
                }
                dirInfo.FilesCount += fis.Length;

                DirectoryInfo[] dis=di.GetDirectories();
                foreach (DirectoryInfo dir in dis)
                {
                    DirInfo child = new DirInfo(dir.Name, dir.FullName);
                    dirInfo.Folders.Add(child);
                    ScanFolder(child, e);

                    dirInfo.TotalLenght += child.TotalLenght;
                    dirInfo.FilesCount += child.FilesCount;
                    dirInfo.FoldersCount += child.FoldersCount;
                }
                dirInfo.FoldersCount += dis.Length;
            }
            catch (UnauthorizedAccessException)
            {
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                scaning = false;
            }

            return dirInfo;
        }

        public void Cancel()
        {
            backgroundWorker1.CancelAsync();
        }

        [Browsable(true)]
        public string Folder { get { return folder; } set { folder = value; } }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            scaning = true;
            driveInfo = new DirInfo(folder, folder);
            ScanFolder(driveInfo, e);
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (ProgressChanged != null)
                ProgressChanged(sender, e);
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            scaning = false;
            if (RunWorkerCompleted != null)
                RunWorkerCompleted(sender, e);
        }

        public DirInfo DirInfo { get { return driveInfo; } }
        public bool Scaning { get { return scaning; } }

        public event ProgressChangedEventHandler ProgressChanged;
        public event RunWorkerCompletedEventHandler RunWorkerCompleted;
    }
}
